##################################################################
# File : /lua/sim/entity.lua
# Description : The Entity lua module
# Author : GPG
##################################################################

SyncMeta = {
    __index = function(t,key)
        local id = rawget(t,'id')
        return EntityData[id].Data[key]
    end,

    __newindex = function(t,key,val)
        #LOG( "SYNC: " .. key .. ' = ' .. repr(val))
        local id = rawget(t,'id')
        
        if not EntityData[id] then
            EntityData[id] = {
                OwnerArmy = rawget(t,'army'),
                Data = {}
            }
        end
        EntityData[id].Data[key] = val

        if not Sync.EntityData[id] then
            Sync.EntityData[id] = {}
        end
        Sync.EntityData[id][key] = val
    end,
}

Entity = Class(moho.entity_methods) {

    __init = function(self,spec)
        _c_CreateEntity(self,spec)
    end,
    
    __post_init = function(self,spec)
        self:OnCreate(spec)
    end,

    OnCreate = function(self,spec)
        self.Spec = spec
    end,
    
    OnDestroy = function(self)
        # Clear out our sync data
        if self.Sync then
            EntityData[self:GetEntityId()] = nil
            Sync.EntityData[self:GetEntityId()] = nil
            
            # Don't allow anyone to stuff anything else in the table
            self.Sync = nil
            
            # Let the user layer know this id is kaput
            Sync.ReleaseIds[self:GetEntityId()] = true
        end
    end,

    GetArmy = function(self)
        return self.Army
    end,
    
    GetPosition = function(self,bone)
        if bone then
            return self:GetBonePosition(bone)
        end
        return self.Position
    end,

    # Each entity optionally has a sync table that when modified stores the new values in the
    # global sync table to copy to the user layer.
    InitSyncTable = function(self)
        self.Sync = {}
        
        # Required to exist before the sync metatable is set
        self.Sync.id = self:GetEntityId()
        self.Sync.army = self:GetArmy()
        
        setmetatable(self.Sync,SyncMeta)

        # Set these again so they actually get sync'd
        self.Sync.EntityId = self:GetEntityId()
        self.Sync.Army = self:GetArmy()
    end,
}